import {Component, OnDestroy, OnInit, TemplateRef} from '@angular/core';
import {combineLatest, Subject} from 'rxjs';
import {TodoService} from '../../../../services/todo/todo.service';
import {ListService} from '../../../../services/list/list.service';
import {List, Todo} from '../../../../../domain/entities';
import {takeUntil} from 'rxjs/operators';
import {floorToDate, getTodayTime} from '../../../../../utils';
import {NzDropdownContextComponent, NzDropdownService, NzMessageService, NzModalService} from 'ng-zorro-antd';
import {RankBy} from '../../../../../domain/type';
import {Router} from '@angular/router';

const rankerGenerator = (type: RankBy = 'title'): any => {
  if (type === 'completedFlag') {
    return (x: Todo, y: Todo) => x.completedFlag && !y.completedFlag;
  }
  return (x: Todo, y: Todo) => {
    return x[type] > y[type];
  };
};

@Component({
  selector: 'app-todo',
  templateUrl: './todo.component.html',
  styleUrls: ['./todo.component.less']
})
export class TodoComponent implements OnInit, OnDestroy {
  private destroy$ = new Subject();

  todos: Todo[] = []; // 代办数组
  lists: List[] = []; // 列表数组

  currentContextTodo: Todo; // 当前代办上下文对象

  private dropdown: NzDropdownContextComponent; // 右键下拉组件

  constructor(
    private router: Router,
    private modal: NzModalService,
    private dropdownService: NzDropdownService, // 下拉菜单服务
    private listService: ListService,
    private todoService: TodoService
  ) {
  }

  ngOnInit() {
    // 订阅列表发生改变
    this.listService.lists$
      .pipe(takeUntil(this.destroy$))
      .subscribe((lists) => {
        this.lists = lists;
      });

    combineLatest([this.listService.currentUuid$, this.todoService.todos$, this.todoService.rankBy$])
      .pipe(takeUntil(this.destroy$))
      .subscribe((sources) => {
        this.processTodos(sources[0], sources[1], sources[2]);
      });

    this.todoService.getAll();
    this.listService.getAll();
  }

  ngOnDestroy(): void {
    this.destroy$.next();
  }

  toggle(uuid: string) {
    this.todoService.toggleTodoComplete(uuid);
  }

  // 添加
  add(title: string): void {
    this.todoService.add(title);
  }

  // 关闭右键菜单
  close() {
    this.dropdown.close();
  }

  // 设为今日
  setToday() {
    this.todoService.setTodoToday(this.currentContextTodo._id);
  }

  // 移动到列表
  moveToList(listUUID: string) {
    this.todoService.moveToList(this.currentContextTodo._id, listUUID);
  }

  delete(uuid: string) {
    this.modal.confirm({
      nzTitle: '确认删除代办事项',
      nzContent: '删除该待办事项后不可恢复，确定要删除吗？',
      nzOnOk: () => {
        this.todoService.delete(uuid);
      }
    });
  }

  listsExcept(uuid: string): List[] {
    return this.lists.filter((list) => list._id !== uuid);
  }

  contextMenu($event: MouseEvent, template: TemplateRef<void>, uuid: string) {
    this.dropdown = this.dropdownService.create($event, template);
    this.currentContextTodo = this.todos.find((todo) => todo._id === uuid);
  }

  click(uuid: string) {
    this.router.navigateByUrl(`/main/${uuid}`);
  }

  // 处理代办事项
  private processTodos(listUUID: string, todos: Todo[], rank: RankBy): void {
    const filteredTodos = todos.filter((todo) => {
      return (
        (listUUID === 'today' && todo.planAt && floorToDate(todo.planAt) <= getTodayTime())
        || (listUUID === 'todo' && (!todo.listUUID || todo.listUUID === 'todo'))
        || (listUUID === todo.listUUID)
      );
    }).map((todo) => Object.assign({}, todo) as Todo).sort(rankerGenerator(rank));

    this.todos = filteredTodos || [];
  }
}
